#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>

#define LEFT "["
#define RIGHT "]"
#define LABLE "$"
#define LINE_SIZE 1024
#define ARGC_SIZE 32
#define DELIM " "
#define EXIT_CODE 44

char myenv[LINE_SIZE];
char commandline[LINE_SIZE];
int quit = 0;
int lastcode = 0;
char pwd[LINE_SIZE];

const char *getusername()
{
    return getenv("USER");
}
const char *Gethostname()
{
    return getenv("HOSTNAME");
}
void getpwd()
{
    //return getenv("PWD");
    getcwd(pwd, sizeof(pwd));
}

void Interact(char *cline, int size)
{
    getpwd();
    printf(LEFT"%s@%s %s"RIGHT LABLE" ", getusername(), Gethostname(), pwd);
    //scanf("%s",commandline);
    char* s = fgets(cline, size, stdin);
    assert(s);
    (void)s;
    cline[strlen(cline)-1] = '\0';

}

int splitstring(char cline[],char *argv[])
{
    int i = 0;
    argv[i++] = strtok(cline, DELIM);
    while(argv[i++] = strtok(NULL, DELIM));
    return i - 1;
}

void NormalExcute(char *argv[])
{

    pid_t id = fork();
    if(id < 0){
        perror("fork");
        return;
    }
    else if(id == 0){
        execvp(argv[0], argv);
        exit(EXIT_CODE);
    }
    else{
        int status = 0;
        pid_t rid = waitpid(id, &status, 0);
        if(rid == id){
            lastcode = WEXITSTATUS(status);
                
        }
    }
}
int buildCommand(char *argv[], int argc)
{
        if(argc == 2 && strcmp(argv[0], "cd") == 0){
            chdir(argv[1]);
            //if(strcmp(argv[0], ".") == 0) continue;
            //else if(strcmp(argv[0], "..") == 0){
            
           // }
            //else{
            getpwd();
            sprintf(getenv("PWD"), " %s",pwd);
                //putenv(argv[1]);
            //}
            return 1;
        }
        if(strcmp(argv[0], "ls") == 0)
        {
            argv[argc++] = "--color";
            argv[argc] = NULL;
        }
        if(argc == 2 && strcmp(argv[0], "export") == 0)
        {
            strcpy(myenv,argv[1]);
            putenv(myenv);
            return 1;
        }
        if(argc == 2 && strcmp(argv[0], "echo") == 0)
        {
            if(argv[1] == "$?")
            {
                printf("%d\n",lastcode);
                lastcode = 0;
            }
            else if(*argv[1] == '$'){
                char* val = getenv(argv[1]+1);
                if(val) printf("%s\n", val);
            }
            else{
                printf("%s\n", argv[1]);
            }
            return 1;
        }

        return 0;

}

int main()
{
    //extern char **environ;
    char *argv[ARGC_SIZE];
    while(!quit)
    {
        Interact(commandline, sizeof(commandline));
        //printf("echo : %s\n", commandline);
       int argc = splitstring(commandline, argv);
       if(argc == 0) continue;
        //for(int i = 0; argv[i]; i++) printf("[%d]: %s\n", i, argv[i]);
        int n = buildCommand(argv, argc);
        if(!n) NormalExcute(argv);
    }
    return 0;
}
